from xen.util.ip import check_subnet, get_current_ipgw
from xen.util.blkif import blkdev_uname_to_file
-from xen.xend.server import channel, controller
+from xen.xend.server import controller
from xen.xend.server import SrvDaemon; xend = SrvDaemon.instance()
from xen.xend.server import messages
-from xen.xend.server.channel import channelFactory
+from xen.xend.server.channel import EventChannel, channelFactory
from xen.xend import sxp
from xen.xend.PrettyPrint import prettyprintstring
self.channel = None
self.store_channel = None
- self.store_mfs = None
+ self.store_mfn = None
self.controllers = {}
self.info = None
def getChannel(self):
return self.channel
+ def getStoreChannel(self):
+ return self.store_channel
+
def update(self, info):
"""Update with info from xc.domain_getinfo().
"""
if self.channel:
sxpr.append(self.channel.sxpr())
+ if self.store_channel:
+ sxpr.append(self.store_channel.sxpr())
console = self.getConsole()
if console:
sxpr.append(console.sxpr())
def destroy(self):
"""Completely destroy the vm.
"""
- self.cleanup()
- self.destroy_domain()
+ try:
+ self.cleanup()
+ except Exception, ex:
+ log.warning("error in domain cleanup: %s", ex)
+ pass
+ try:
+ self.destroy_domain()
+ except Exception, ex:
+ log.warning("error in domain destroy: %s", ex)
+ pass
def destroy_domain(self):
"""Destroy the vm's domain.
devices have been released.
"""
if self.channel:
- self.channel.close()
- self.channel = None
+ try:
+ self.channel.close()
+ self.channel = None
+ except:
+ pass
if self.image:
try:
self.image.destroy()
if not self.restore:
self.setdom(dom)
- def create_channel(self):
- """Create the control channel to the domain.
- If saved info is available recreate the channel using the saved ports.
+ def openChannel(self, name, local, remote):
+ """Create a channel to the domain.
+ If saved info is available recreate the channel.
+
+ @param local default local port
+ @param remote default remote port
"""
local = 0
remote = 1
if self.savedinfo:
- info = sxp.child(self.savedinfo, "channel")
+ info = sxp.child(self.savedinfo, name)
if info:
local = int(sxp.child_value(info, "local_port", 0))
remote = int(sxp.child_value(info, "remote_port", 1))
- self.channel = channelFactory().openChannel(str(self.id),
- local_port=local,
- remote_port=remote)
+ chan = channelFactory().openChannel(self.id, local_port=local,
+ remote_port=remote)
+ return chan
+
+ def eventChannel(self, name):
+ return EventChannel.interdomain(0, self.id)
+
+ def create_channel(self):
+ """Create the channels to the domain.
+ """
+ self.channel = self.openChannel("channel", 0, 1)
+ self.store_channel = self.eventChannel("store_channel")
def create_configured_devices(self):
devices = sxp.children(self.config, 'device')
RESPONSE_TIMEOUT = 20.0
-def eventChannel(dom1, dom2):
- """Create an event channel between domains.
- The returned dict contains dom1, dom2, port1 and port2 on success.
+class EventChannel(dict):
+ """An event channel between domains.
+ """
+
+ def interdomain(cls, dom1, dom2, port1=0, port2=0):
+ """Create an event channel between domains.
+
+ @return EventChannel (None on error)
+ """
+ v = xc.evtchn_bind_interdomain(dom1=dom1, dom2=dom2,
+ port1=port1, port2=port2)
+ if v:
+ v = cls(dom1, dom2, v)
+ return v
+
+ interdomain = classmethod(interdomain)
+
+ def __init__(self, dom1, dom2, d):
+ d['dom1'] = dom1
+ d['dom2'] = dom2
+ self.update(d)
+ self.dom1 = dom1
+ self.dom2 = dom2
+ self.port1 = d.get('port1')
+ self.port2 = d.get('port2')
+
+ def close(self):
+ """Close the event channel.
+ """
+ def evtchn_close(dom, port):
+ try:
+ xc.evtchn_close(dom=dom, port=port)
+ except Exception, ex:
+ pass
+
+ if DEBUG:
+ print 'EventChannel>close>', self
+ evtchn_close(self.dom1, self.port1)
+ evtchn_close(self.dom2, self.port2)
+
+ def sxpr(self):
+ return ['event-channel',
+ ['dom1', self.dom1 ],
+ ['port1', self.port1 ],
+ ['dom2', self.dom2 ],
+ ['port2', self.port2 ]
+ ]
- @return dict (empty on error)
+ def __repr__(self):
+ return ("<EventChannel dom1:%s:%s dom2:%s:%s>"
+ % (self.dom1, self.port1, self.dom2, self.port2))
+
+def eventChannel(dom1, dom2, port1=0, port2=0):
+ """Create an event channel between domains.
+
+ @return EventChannel (None on error)
"""
- evtchn = xc.evtchn_bind_interdomain(dom1=dom1, dom2=dom2)
- if evtchn:
- evtchn['dom1'] = dom1
- evtchn['dom2'] = dom2
- return evtchn
+ return EventChannel.interdomain(dom1, dom2, port1=port1, port2=port2)
def eventChannelClose(evtchn):
- """Close an event channel that was opened by eventChannel().
+ """Close an event channel.
"""
- def evtchn_close(dom, port):
- if (dom is None) or (port is None): return
- try:
- xc.evtchn_close(dom=dom, port=port)
- except Exception, ex:
- pass
-
if not evtchn: return
- if DEBUG:
- print 'eventChannelClose>', evtchn
- evtchn_close(evtchn.get('dom1'), evtchn.get('port1'))
- evtchn_close(evtchn.get('dom2'), evtchn.get('port2'))
-
+ evtchn.close()
class ChannelFactory:
- """Factory for creating channels.
+ """Factory for creating control channels.
Maintains a table of channels.
"""
""" Channels indexed by index. """
- channels = {}
+ channels = None
thread = None
notifier = None
"""Map of ports to the virq they signal."""
- virqPorts = {}
+ virqPorts = None
def __init__(self):
"""Constructor - do not use. Use the channelFactory function."""
+ self.channels = {}
+ self.virqPorts = {}
self.notifier = xu.notifier()
# Register interest in virqs.
self.bind_virq(xen.lowlevel.xc.VIRQ_DOM_EXC)
self.virqPorts[port] = virq
log.info("Virq %s on port %s", virq, port)
- def virq(self):
- log.error("virq")
- self.notifier.virq_send(self.virqPort)
-
def start(self):
"""Fork a thread to read messages.
"""
return None
def openChannel(self, dom, local_port=0, remote_port=0):
- return (self.findChannel(dom, local_port=local_port, remote_port=remote_port)
- or
- self.newChannel(dom, local_port, remote_port))
+ chan = self.findChannel(dom, local_port=local_port,
+ remote_port=remote_port)
+ if chan:
+ return chan
+ chan = self.newChannel(dom, local_port, remote_port)
+ return chan
+
def createPort(self, dom, local_port=0, remote_port=0):
"""Create a port for a channel to the given domain.
return inst
class Channel:
- """Chanel to a domain.
+ """Control channel to a domain.
Maintains a list of device handlers to dispatch requests to, based
on the request type.
"""